import fire
import json
import random
import re
import os

from metagpt.const import MESSAGE_ROUTE_TO_NONE
from metagpt.logs import logger, define_log_level
from metagpt.roles import Role
from metagpt.schema import Message
from metagpt.team import Team

from all_actions import *
from game_judger_v2 import DealCards, GameJudger


define_log_level(print_level="ERROR", logfile_level="DEBUG")

# all role class here

class MathProdigy(Role):
    name: str = "Gauss"
    profile: str = "MathProdigy"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._watch([CallMathProdigy])
        self.set_actions([MachineGiveExpression])


class GamePlayer(Role):
    name: str = "David"
    profile: str = "GamePlayer"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.set_actions([GetHumanReply])
        self._watch([DealCards, WrongExpression])

    async def _act(self) -> Message:        
        context = self.get_memories() 
        point_list = get_recent_point_list(context)
        card_list = get_random_card_list(point_list)
        
        todo = self.rc.todo

        cards_content = f"{{'card_list': {card_list}, 'point_list': {point_list}}}"
        human_reply = await todo.run(cards_content)
        
        if human_reply == "deal":
            self.rc.env.publish_message(Message(content="RequireDealCardsAgain", cause_by=RequireDealCardsAgain))
        elif human_reply == "exit":
            self.rc.env.publish_message(Message(content="ExitGame", cause_by=ExitGame))
        elif human_reply == "help":
            self.rc.env.publish_message(Message(content="CallMathProdigy", cause_by=CallMathProdigy))
        else:
            self.rc.env.publish_message(Message(content=human_reply, cause_by=HumanGiveExpression))
            
        return Message(content="dummy message", send_to=MESSAGE_ROUTE_TO_NONE)


async def main(
    idea: str = "play 24 points game with me",
    investment: float = 3.0,
    n_round: int = 500,
    lm_family: str = "qwen"):

    logger.info(idea)

    set_lm_config(lm_family)
    main_lm = get_main_lm()
        
    team = Team(use_mgx=False)
    team.hire(
        [
            MathProdigy(config=main_lm),
            GameJudger(config=main_lm),
            GamePlayer(is_human=True),
        ]
    )

    team.invest(investment=investment)
    team.run_project(idea)
    await team.run(n_round=n_round)

    

if __name__ == "__main__":
    fire.Fire(main)

